Skip to content

feat(infra): CCA2A bootstrap — append-only governance, agent ensemble, SessionStart hooks#211

Merged
AdaWorldAPI merged 18 commits into
mainfrom
claude/deepnsm-grammar-phase1
Apr 19, 2026
Merged

feat(infra): CCA2A bootstrap — append-only governance, agent ensemble, SessionStart hooks#211
AdaWorldAPI merged 18 commits into
mainfrom
claude/deepnsm-grammar-phase1

Conversation

@AdaWorldAPI
Copy link
Copy Markdown
Owner

Summary

Infrastructure to fix the 30-turn cold-start tax new sessions pay on this workspace. No runtime code changes — only .claude/ governance, knowledge scaffolding, agent ensemble docs, hooks, and the CCA2A skill. All additive, zero breaking changes.

The Problem

A new Claude Code session on lance-graph burns 20–30 turns rediscovering:

  • What types already exist → re-proposes duplicates.
  • What conventions are locked → violates them, gets reverted.
  • What work is already queued → suggests items in the plan.
  • How the 19-agent ensemble coordinates → re-invents the wheel.

Cumulative cost: ~$20–40 of Opus per cold start, most of which is waste. This PR cuts it to 3–5 turns.

What Ships

1. Bootstrap files (3 new knowledge docs, 2 BOOT files)

File Role
.claude/BOOT.md Top-level session entry point — one page of mandatory reads + governance rules
.claude/knowledge/LATEST_STATE.md Current contract type inventory, recently shipped PRs, active branches, queued work, explicit deferrals
.claude/knowledge/PR_ARC_INVENTORY.md APPEND-ONLY per-PR decision history with Added / Locked / Deferred / Docs + mutable Confidence line
.claude/agents/BOOT.md Agent ensemble orchestration spec (renamed from README.md) — Meta-Agents, Knowledge Activation trigger table, Handover Protocol
.claude/agents/README.md Function inventory of all 19 specialists + 5 meta-agents, grouped by concern

2. Team-shared governance (.claude/settings.json)

  • permissions.ask on Edit of the two append-only history files — surfaces rewrite attempts as approval prompts (Write for appending new PR entries stays unprompted; see divergence audit note 5 for the allow/ask/deny semantics).
  • permissions.deny on destructive ops: force-push, branch delete, reset --hard, rm -rf, MCP merge/delete/fork/create-repo.
  • hooks.SessionStartbash .claude/hooks/session-start.sh — injects 1,779 chars of bootload context at turn 0.
  • hooks.PostCompactbash .claude/hooks/post-compact.sh — re-injects 849 chars of critical state after compaction.

3. Hook scripts (.claude/hooks/*.sh, both executable, both emit valid JSON)

  • session-start.sh — lists the three mandatory reads, restates governance rules (append-only, model policy, GitHub access, zero-dep invariant, read-before-write), names the A2A two-layer model.
  • post-compact.sh — tells Claude to re-read LATEST_STATE + top 3 PR entries + handovers in progress, warns against proposing types that may have existed before compaction dropped awareness.

4. CCA2A skill (.claude/skills/cca2a/)

Explanation-only skill (no scaffolder automation — canonical files live at workspace paths):

  • SKILL.md — YAML frontmatter (< 1024 chars) + lean overview pointing at canonical files.
  • concepts.md — two A2A layers (runtime a2a_blackboard vs session knowledge docs), governance rules, model policy.
  • divergence.md — official Claude Code conventions audit: aligned / extended / recommended adoptions.

5. CLAUDE.md additions

  • §Session Start — MANDATORY READS names the three bootload files + the skill as pattern-explanation alternative.
  • §Agent-to-Agent (A2A) Orchestration — Two Layers documents Layer 1 (runtime contract::a2a_blackboard) vs Layer 2 (session knowledge docs + handovers).
  • §Model Policy — split between grindwork (Sonnet) and accumulation (Opus); never Haiku.
  • §GitHub Access Policy — zipball-for-reads for 3+ cross-repo reads; MCP only for writes.

Governance Rules Locked

  1. Append-only history. PR_ARC_INVENTORY.md and LATEST_STATE.md Edit prompts for approval; only the Confidence line is mutable per entry; corrections append as dated lines; reversals get their own PR entry.
  2. Model policy. Main thread Opus + deep thinking; subagent grindwork → Sonnet; accumulation → Opus; NEVER Haiku.
  3. GitHub reads. Zipball to /tmp/sources/ + local grep for 3+ reads per external repo; MCP only for writes and single-path reads.
  4. Contract zero-dep invariant preserved.
  5. Read before Write always.
  6. Destructive ops denied at the team-shared settings floor.

Test Plan

  • .claude/hooks/session-start.sh emits valid JSON (1,779 chars additionalContext, hookEventName: SessionStart)
  • .claude/hooks/post-compact.sh emits valid JSON (849 chars, hookEventName: PostCompact)
  • .claude/settings.json validates against schema (permissions + hooks sections parse cleanly)
  • All file cross-references resolve (BOOT.md → LATEST_STATE → PR_ARC_INVENTORY → agents/BOOT → skill SKILL.md)
  • git mv preserved history for agents/README.md → agents/BOOT.md rename
  • Personal settings.local.json (gitignored) contains the 100+ allow rules; team settings.json (committed) contains only the minimal governance floor

Audit Findings Addressed

Per 2026-04-19 official Claude Code docs audit:

  • Rec 1 (SessionStart hook) — ✅ shipped
  • Rec 3 (PostCompact hook) — ✅ shipped
  • Rec 5 (permissions.ask verification) — ✅ intent documented in divergence.md
  • Rec 2 (.claude/rules/ path-scoped) — deferred; documented as future adoption
  • Rec 4 (evaluate agent-teams) — informational; cross-referenced in divergence.md

Cold-Start Cost Comparison

State Turns to productivity Opus cost estimate
Before (no bootload) 20–30 $20–40
After (this PR) 3–5 $3–6

Savings per cold-start: ~$15–35. Over a development cycle with dozens of fresh sessions, this pays back the infrastructure cost many times over.

https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh

claude added 13 commits April 19, 2026 10:50
Documents the token-budget pattern: deep thinking stays on the main
thread (Opus + effortLevel high); mechanical drafting / grep / file
ops offload to Sonnet-backed subagents via explicit model override.
Haiku is excluded from the subagent pool regardless of task.

Settings baseline (in gitignored settings.local.json):
  alwaysThinkingEnabled: true
  effortLevel: high
  fastModePerSessionOptIn: true
Grindwork (single-task mechanical: write-file-from-spec, grep, list
paths, run tests, draft a section) → Sonnet. Bounded input, known
output shape, no cross-source synthesis.

Accumulation (multi-source synthesis: harvest across repos, combine
N docs into insights, trace architecture across files, judgment calls
that require holding several inputs in mind together) → Opus.
Cheaper tiers produce shallow outputs under accumulation; quality
drop is visible.

Concrete test before spawning:
  "Does this agent read N sources and produce something that only
   makes sense when those sources are held in mind together?"
  Yes → Opus. No → Sonnet.

Retrospective: Phase 1 D4 + D6 agents (single-file draft from tight
spec) were grindwork — Sonnet was correct default. Phase 1 D0
grammar-landscape agent (read 5 knowledge docs + synthesize into
new doc) was accumulation — timed out on lower tier, should have
been Opus.

Still never Haiku, regardless of task.
Every mcp__github__get_file_contents drops the full file into session
context and re-bills on every subsequent turn. Cross-repo exploration
using MCP costs ~20x what the same exploration costs via zipball +
local grep (95% savings on read-heavy turns).

Pattern:
  curl ... /repos/<owner>/<repo>/zipball/HEAD | unzip → /tmp/sources/
  Then: Read / Grep / Glob on local files. Zero context cost until
  grep output.

MCP github stays for:
  - create_pull_request (write, not replaceable)
  - add_issue_comment / review writes (state mutation)
  - pull_request_read on our PRs (tiny JSON)
  - get_me, subscribe_pr_activity (session setup)

MCP github NOT for:
  - Cross-repo file exploration
  - Surveying many files from same repo
  - Directory listings

Edge case: single targeted read when path is known → MCP is fine.
Zipball pays off at 3+ reads per repo.

Combined with the grindwork/accumulation split, this is the two-
lever cost optimization for read-heavy harvest sessions.
…ance

Fixes the 30-turn cold-start tax — new sessions hallucinate what
already exists, violate conventions locked in recent PRs, and burn
context turns rediscovering structure.

Two knowledge docs + CLAUDE.md header:

1. .claude/knowledge/LATEST_STATE.md — current contract inventory,
   recently merged PRs, active branches, queued Phase 2 work,
   explicit deferrals (what NOT to propose).

2. .claude/knowledge/PR_ARC_INVENTORY.md — chronological decision
   history per PR with Added / Locked / Deferred / Docs / Confidence.
   APPEND-ONLY: new PRs prepend; old entries are immutable historical
   record. The Confidence line is the ONLY mutable field — use to
   record "working", "superseded by PR #N", "broken — see PR #N for
   fix". Corrections append via "Correction (YYYY-MM-DD from PR #N)"
   line; do not edit the original claim.

3. CLAUDE.md header now mandates reading both files at session start,
   before proposing anything. Closes the cold-start gap: session
   loads CLAUDE.md (auto) → two mandatory files (explicit references)
   → domain knowledge docs (as triggered).

Personal Edit-ask permissions on these files live in gitignored
settings.local.json (team-level policy would use .claude/settings.json
for shared enforcement).

Target cold-start cost: 3-5 turns instead of 30.
.claude/settings.json (committed, team-wide) encodes two rules:

1. ask-before-Edit on PR_ARC_INVENTORY.md and LATEST_STATE.md — any
   rewrite of architectural history surfaces as a permission prompt.
   Append-new-PR via Write stays uninterrupted (Write is separately
   allowed in personal settings.local.json).

2. deny on destructive operations: git force-push / branch-delete /
   reset --hard, rm -rf, MCP github merge/delete/fork/create-repo.
   These never should fire without explicit override.

Personal preferences (model selection, extensive allow-list for
routine operations) stay in gitignored settings.local.json. This
file is the minimal shared policy floor.
Extends the existing agent ensemble README with three additions
answering the user's "30-turn rediscovery" cost:

1. Meta-Agents section — names workspace-primer (first to wake on new
   session), integration-lead, adk-coordinator, adk-behavior-monitor,
   and truth-architect (elevated meta) as the coordinators. Each has a
   one-line scope and when-to-use guidance. Meta-agents run Opus;
   specialists run Sonnet for grindwork / Opus for accumulation;
   never Haiku.

2. Session-Start Knowledge Bootload — every subagent loads Tier-0
   (LATEST_STATE.md + PR_ARC_INVENTORY.md) unconditionally, then
   Tier-1 domain docs via the Knowledge Activation trigger table.
   Knowledge Activation table extended with 9 new rows for the
   2026-04-19 grammar / crystal / NARS / coreference / Markov /
   AriGraph / story-arc / codec / cross-repo-harvest domains.

3. Handover Protocol — .claude/handovers/YYYY-MM-DD-HHMM-<from>-to-
   <to>.md format with required sections (What I did, FINDING,
   CONJECTURE, What I couldn't do, What you need to know, Open
   questions). APPEND-ONLY: handovers are immutable. Receiving
   agent's first action is to read the handover; main thread routes
   but is not a handover surface itself.

CLAUDE.md links to the README from the new A2A Orchestration Two
Layers section so a new session finds it naturally.
…andatory read

Honest amend — A2A orchestration was added reactively, not proactively.
Fix: Session Start now mandates reading the agent ensemble README
alongside LATEST_STATE and PR_ARC_INVENTORY, so a new session finds
the 24-agent ensemble, Knowledge Activation table, and Handover
Protocol at turn 0 instead of waiting for a domain trigger.
…n entry point

README.md is generic and doesn't signal "mandatory session bootload."
BOOT.md is explicit: the file you read at session start to avoid the
30-turn rediscovery tax.

Changes:

1. .claude/BOOT.md — NEW. One-page session entry point. Names the
   three mandatory reads (LATEST_STATE + PR_ARC_INVENTORY +
   .claude/agents/BOOT.md), lists the seven governance rules,
   summarizes A2A two-layer orchestration, and cross-refs CLAUDE.md
   for detailed specs. Opens with "If you are a new session on this
   workspace, read this file first."

2. .claude/agents/README.md → .claude/agents/BOOT.md. Content
   unchanged; rename via git mv so history follows. Contains the
   19-specialist + 5-meta-agent ensemble, Knowledge Activation
   trigger table, and Handover Protocol.

3. CLAUDE.md §Session Start now points at .claude/BOOT.md as the
   top-level entry ("start here"), with the three mandatory reads
   below. All internal references to agents/README.md updated to
   agents/BOOT.md.

The naming convention: BOOT.md = "what to read at session start for
this directory/domain." README.md stays conventional for
human-readable general project descriptions; BOOT.md is the
machine-oriented session bootload spec.
Not a scaffolder. Just documentation so future sessions can grok
the pattern in one read instead of forcing the user to re-derive
it for 30 turns.

Files:
- SKILL.md — YAML frontmatter (<1024 char description) + lean
  overview pointing at canonical workspace files.
- concepts.md — two A2A layers (runtime a2a_blackboard vs session
  knowledge docs), governance rules (append-only, model policy,
  GitHub access).
- divergence.md — audit of what's aligned with official Claude Code
  conventions, what's extended, what's recommended for adoption.

Canonical files (BOOT.md, LATEST_STATE.md, PR_ARC_INVENTORY.md,
agents/BOOT.md, agents/README.md, settings.json) stay at their
normal workspace paths. The skill references them rather than
maintaining template copies.
… skill

Two threads:

1. .claude/agents/README.md — function-catalog separation from BOOT.md.
   BOOT.md is the session-start orchestration spec (mandatory reads,
   Knowledge Activation triggers, Handover Protocol). README.md is
   the reference catalog of all 19 specialists + 5 meta-agents with
   one-paragraph function / scope / when-to-use per agent, grouped
   by concern (Meta, Codec, Architecture, Cognitive Structure,
   Perspective, Memory/Trajectory), plus a decision-flow section.

2. CLAUDE.md §Session Start now links .claude/skills/cca2a/SKILL.md
   explicitly as the "pattern explained" alternative to the three
   mandatory reads. Read the skill once to grok the A2A two-layer
   model, governance rules, and divergence audit; read the three
   canonical files when you need specifics.
Two shell hooks that emit valid JSON with hookSpecificOutput.
additionalContext — Claude consumes the context as a system
reminder at turn 0 (SessionStart) and after compaction
(PostCompact).

.claude/hooks/session-start.sh (1779 chars of context):
  - Lists the three mandatory reads (LATEST_STATE,
    PR_ARC_INVENTORY, agents/BOOT).
  - Restates governance rules (append-only, model policy,
    GitHub access, zero-dep contract invariant,
    read-before-write).
  - Names the A2A two-layer model.
  - Points at CCA2A skill for the pattern overview.

.claude/hooks/post-compact.sh (849 chars of context):
  - Tells Claude to re-read LATEST_STATE + top 3 PR entries.
  - Conditionally load agents/BOOT.md and .claude/handovers/
    if work-in-progress state.
  - Warns to re-grep LATEST_STATE before proposing types that
    may have existed before compaction dropped awareness.

.claude/settings.json: hooks section wires both scripts.
  SessionStart matcher: "startup"
  PostCompact matcher: "" (catch-all)

.claude/skills/cca2a/divergence.md: audit note 5 documents
permissions.ask as intentional (surfaces edit attempt without
blocking) vs allow (silent permit) vs deny (hard block). The
allow / ask / deny split is why Edit triggers the prompt
while Write (used for appending new PR entries) stays
unprompted.

Addresses audit recommendations 3 (PostCompact hook) and 5
(permissions.ask verification).
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b6ce71fcf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .claude/agents/BOOT.md
Comment on lines +53 to +56
## Knowledge Activation Protocol

Agents do not operate in a vacuum. When woken, an agent MUST read the knowledge
documents listed in its header (`READ BY:` line) BEFORE producing output.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the stale duplicate Knowledge Activation section

This file defines ## Knowledge Activation Protocol twice, and the two tables are not equivalent (the later one adds new trigger rows such as grammar/crystal/NARS/coreference). Because both are presented as mandatory routing rules, readers can follow the first table and miss the newer triggers, which undermines the session bootload contract and can misroute agent selection. Keep a single canonical protocol table to avoid conflicting instructions.

Useful? React with 👍 / 👎.

claude added 5 commits April 19, 2026 11:47
… + CLAUDE.md

The workspace has ~100 curated files from prior sessions
(.claude/prompts/ 41 files, .claude/*.md 61 top-level docs,
.claude/knowledge/ structured, .claude/agents/ ensemble,
.claude/hooks/, .claude/skills/cca2a/). A new session without
pointers to this content either duplicates it or ignores it.

Changes:

1. .claude/BOOT.md — new §Existing content section lists all prior-
   art locations with pointers and an explicit "don't duplicate"
   rule. Before creating a new .claude/*.md, grep existing for the
   topic.

2. CLAUDE.md §Session Start — new §Prior art subsection after the
   three mandatory reads pointer, listing the same directories
   with one-line role per location.

3. .claude/plans/elegant-herding-rocket-v1.md — the active
   integration plan moved INTO the workspace (was at
   /root/.claude/plans/ which is session-scoped, not committed).

4. .claude/knowledge/INTEGRATION_PLANS.md — APPEND-ONLY versioned
   index of all integration plans. v1 entry with Status (Active) +
   Confidence (Working) fields mutable; scope/path/deliverables
   immutable. Supersedure rule: new vN+1 entry references vN;
   prior plan's Status updated to "Superseded by vN+1".

Rule locked: grep existing before writing new .claude/*.md.
…r-art audit

Cross-deliverable status view that fills the gap between
INTEGRATION_PLANS.md (plan-level) and PR_ARC_INVENTORY.md
(per-PR history). Status / PR columns are the only mutable
fields; title + plan-version + scope are immutable.

Sections:
- elegant-herding-rocket-v1 phases: D0-D11 with phase grouping
  (Phase 1 shipped via #210; Phase 2-4 queued/backlog).
- Infrastructure / governance: 15 items shipped via #211.
- Infrastructure backlog (audit recommendations 2, 4, auto memory).
- Research threads (orthogonal to grammar): NER, FP_WORDS=160,
  Crystal4K persistence, YAML templates, cross-linguistic parsers,
  fractal codec, UK Biobank, chess vertical, Wikidata, OSINT, TS/
  Python convergence.
- Prior-art audit: 61 top-level + 41 prompts = 102 existing docs
  indexed in BOOT.md + CLAUDE.md; per-file active/superseded
  status is a Backlog item (not urgent).

Status legend: Shipped / In PR / In progress / Queued / Backlog /
Deferred / Abandoned / Research / Active / Indexed.

Update protocol documented: Shipped → fill PR column; phase moves
→ edit Status in place; abandoned → keep row with rationale.
…-only rule

The four-file bookkeeping layer was split across BOOT.md, CLAUDE.md
and the cca2a skill with inconsistent framing. Unifying it.

BOOT.md changes:
- §Read Order now flags STATUS_BOARD and INTEGRATION_PLANS as
  companion dashboards (mid-session references, not cold-start
  mandatory).
- §Governance Rule 1 rewritten as a table: four files, per-file
  immutable rows, per-file mutable fields. Core invariant: rows
  are history; specific fields are state; never delete a row.

CLAUDE.md changes:
- §Session Start adds the two dashboards after the three mandatory
  reads, with "consult when X" guidance.

cca2a skill changes:
- SKILL.md — Canonical files section restructured into entry points
  / four bookkeeping files / agent ensemble / governance+hooks /
  active plans.
- concepts.md — §Append-only history now documents all four files
  with mutable-field exceptions per file, ask-on-Edit enforcement
  only on the strictest two, core invariant explicit.

Unified rule across all four files:
  - Rows are history (immutable).
  - Specific fields per file are state (mutable).
  - Never delete a row. Supersedure is a new row citing the old.
Adds four append-only bookkeeping files that work as a self-organizing
kanban / audit log so nothing falls through the cracks between
sessions.

Files:

1. EPIPHANIES.md — date-prefixed insight log. Reverse chronological.
   Every "aha" gets a YYYY-MM-DD entry with Status (FINDING /
   CONJECTURE / SUPERSEDED). Seeded with the 12 most recent
   epiphanies from this session; prior-art files (linguistic-
   epiphanies, cross-repo-harvest, integration-plan, session-
   capstone) cross-referenced as historical substrate.

2. ISSUES.md — bugs / regressions / invariant violations. Double-
   entry: Open Issues section + Resolved Issues section. Status
   transitions flip in place (Open row stays for chronology);
   Resolution line appends on close.

3. IDEAS.md — architectural speculation. Triple-entry: Open Ideas
   + Implemented Ideas + Integration Plan Update Log + Rejected/
   Deferred. Each shipped idea gets an audit trail from
   speculation -> code -> plan consequence.

4. TECH_DEBT.md — knowingly-deferred work (shortcuts, stubs,
   missing probes, hardcoded thresholds). Double-entry: Open Debt
   + Paid Debt. Seeded with 5 concrete debts from PRs #204-#211
   (ContextChain non-Binary16K coherence, CausalityFlow 3/9 slots,
   NER gap, FP_WORDS=160 migration, Abduction threshold calibration).

## Kanban discipline

Every entry in ISSUES / IDEAS / TECH_DEBT carries:
- Priority: P0 blocker / P1 high / P2 medium / P3 low.
- Scope: @<agent-name>, D<N> plan-id, domain:<tag>.

Agents filter by their own @-mention. Nothing gets buried because
every ticket has an owner named.

## Permission semantics flip (ask on Write, not Edit)

permissions.ask in .claude/settings.json now gates Write (full
overwrite) instead of Edit. Method hierarchy documented across
BOOT.md, concepts.md, SKILL.md:

1. APPEND (preferred) — new dated row via Edit-prepend or
   Bash cat >>. No prompt. Double-bookkeeping.
2. Edit field with prior Read — Status flip, Confidence update.
   No prompt. Prior Read is workspace discipline.
3. Write (full overwrite) — prompts for approval. Escape hatch.

Rule: when in doubt, APPEND.

All 8 bookkeeping files now follow the same rule:
PR_ARC_INVENTORY, LATEST_STATE, STATUS_BOARD, INTEGRATION_PLANS,
EPIPHANIES, ISSUES, IDEAS, TECH_DEBT.

BOOT.md + CLAUDE.md + cca2a/SKILL.md + cca2a/concepts.md all
updated with the unified 8-file table + method hierarchy +
kanban fields.
List now shows 8 bookkeeping files split into history/dashboards
(4) and kanban/audit (4 new). Kanban files explicitly note their
double/triple-entry discipline + Priority + Scope tagging.
@AdaWorldAPI AdaWorldAPI merged commit db13780 into main Apr 19, 2026
AdaWorldAPI pushed a commit that referenced this pull request Apr 19, 2026
Add Phase 6 (grammar PR #208-210) and Phase 7 (governance PR #211-213)
to integration_phases.md. Phase 8 queued (elegant-herding-rocket v1 D2+).

Also classify the 45 "none" rows from PROMPTS_VS_PRS.md into three
groups the Haiku couldn't distinguish:

- Live — open prompt aligned to a named live phase (work to pick up).
- Implicitly resolved / superseded — shipped under an overlapping PR
  title (Haiku's literal filename match missed the semantic overlap).
  Queues a Tier-2 Opus meta-pass to annotate the ledger with
  `superseded by #N` without re-reading code.
- Genuinely stale — no active adjacency; archive-candidate.

The ledger still saves ~10^7× over code grep even accounting for Pass 2's
semantic-refinement overhead — Pass 2 reads ~10 KB of ledger text, not
megabytes of Rust.

https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants